%%----------------------------------------------------
%% 方法调用 不要求返回执行
%% @author whjing2011@gmail.com
%%----------------------------------------------------
-module(fun_call).
-export([
        exec/2
        ,exec/3
        ,trans_begin/0
        ,trans_flush/0
        ,trans_clean/0
    ]).
-include("common.hrl").

%% @doc 执行方法
exec(Fun, Args) -> 
    exec(undefined, Fun, Args).

%% @doc 方法执行
exec(Mod, Fun, Args) ->
    case get(fun_call_transaction) of
        undefined -> do_exec(Mod, Fun, Args);
        [] -> do_exec(Mod, Fun, Args);
        [H] -> put(fun_call_transaction, [[{Mod, Fun, Args} | H]]);
        [H | T] -> put(fun_call_transaction, [[{Mod, Fun, Args} | H] | T])
    end.

%% @doc 开启事务
trans_begin() ->
    case get(fun_call_transaction) of
        L = [_ | _] ->
            put(fun_call_transaction, [[] | L]);
        _ -> 
            put(fun_call_transaction, [[]])
    end,
    ok.

%% @doc 执行事务
trans_flush() ->
    case get(fun_call_transaction) of
        [] -> ?ERR("方法调用时发生异常:缓冲区为空");
        [[]] -> %% 没有数据，不需要发送
            put(fun_call_transaction, []);
        [H] -> %% 已经是最后一层的事务了，可以直接发送
            [do_exec(Mod, Fun, Args) || {Mod, Fun, Args} <- H],
            put(fun_call_transaction, []);
        [H, H1 | T] ->
            put(fun_call_transaction, [lists:concat([lists:reverse(H), H1]) | T]);
        [H | T] ->
            put(fun_call_transaction, [lists:concat([lists:reverse(H), T])])
    end,
    ok.

%% @doc 关闭一层事务
trans_clean() ->
    case get(fun_call_transaction) of
        [] -> ?ERR("方法调用事务数据时发生异常:缓冲区为空");
        [_H] ->
            put(fun_call_transaction, []);
        [_H | T] ->
            put(fun_call_transaction, T);
        _ ->
            skip
    end,
    ok.

%%-----------------------------------
%% 内部方法
%%-----------------------------------

%% 方法调用执行
do_exec(undefined, Fun, Args) ->
    catch erlang:apply(Fun, Args);
do_exec(Mod, Fun, Args) ->
    catch erlang:apply(Mod, Fun, Args).
